import 'package:flutter/material.dart';

typedef ValueFormat<String> = String Function(double value);

class TextThumbShape extends SliderComponentShape {
  TextThumbShape({this.radius = 15, this.fillColor, this.border, this.style = const TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w600), this.valueFormat, this.radians});
  final double radius;
  final Color? fillColor;
  final BorderSide? border;
  final TextStyle style;
  final ValueFormat? valueFormat;
  final double? radians;

  @override
  Size getPreferredSize(bool isEnabled, bool isDiscrete) {
    return Size(radius * 2, radius * 2);
  }

  @override
  void paint(PaintingContext context, Offset center,
      {required Animation<double> activationAnimation,
      required Animation<double> enableAnimation,
      required bool isDiscrete,
      required TextPainter labelPainter,
      required RenderBox parentBox,
      required SliderThemeData sliderTheme,
      required TextDirection textDirection,
      required double value,
      required double textScaleFactor,
      required Size sizeWithOverflow}) {
    final Canvas canvas = context.canvas;
    final rect = Rect.fromCenter(center: center, width: radius * 2, height: radius * 2);
    final rrect = RRect.fromRectAndRadius(rect, Radius.circular(radius));

    if (fillColor != null) {
      final paint = Paint()
        ..color = fillColor!
        ..style = PaintingStyle.fill;
      canvas.drawRRect(rrect, paint);
    }
    if (border != null) {
      final borderPaint = Paint()
        ..color = border!.color
        ..style = PaintingStyle.stroke
        ..strokeWidth = border!.width;
      canvas.drawRRect(rrect, borderPaint);
    }
    final text = valueFormat != null ? valueFormat!(value) : value.toString();
    final textSpan = TextSpan(
      text: text,
      style: style,
    );
    final textPainter = TextPainter(
      text: textSpan,
      textDirection: TextDirection.ltr,
    );
    textPainter.layout();
    canvas.save();
    canvas.translate(center.dx, center.dy);
    if (radians != null) canvas.rotate(radians!);
    textPainter.paint(
      canvas,
      Offset(
        -textPainter.width / 2,
        -textPainter.height / 2,
      ),
    );
    canvas.restore();
  }
}

class ImageSliderThumbShape extends SliderComponentShape {
  ImageSliderThumbShape({required this.imageName, required this.size}) {
    _loadImage();
  }
  final String imageName;
  final Size size;
  ImageInfo? _imageInfo;

  void _loadImage() {
    final image = AssetImage(imageName);
    final imageProvider = image.resolve(const ImageConfiguration());

    imageProvider.addListener(ImageStreamListener((ImageInfo info, bool synchronousCall) {
      _imageInfo = info;
    }));
  }

  @override
  Size getPreferredSize(bool isEnabled, bool isDiscrete) {
    return size;
  }

  @override
  void paint(PaintingContext context, Offset center,
      {required Animation<double> activationAnimation,
      required Animation<double> enableAnimation,
      required bool isDiscrete,
      required TextPainter labelPainter,
      required RenderBox parentBox,
      required SliderThemeData sliderTheme,
      required TextDirection textDirection,
      required double value,
      required double textScaleFactor,
      required Size sizeWithOverflow}) {
    if (_imageInfo != null) {
      context.canvas.drawImageRect(
        _imageInfo!.image,
        Rect.fromLTWH(0, 0, _imageInfo!.image.width.toDouble(), _imageInfo!.image.height.toDouble()),
        Rect.fromCenter(center: center, width: size.width, height: size.height),
        Paint(),
      );
    }
  }
}
